<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable;
    use SoftDeletes;

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
        'email_verified_at',
        'phone',
        'nickname',
        'avatar',
        'default_book_id',
        'membership_expires_at',
        'membership_type',
        'openid',
    ];

    protected $appends = [
        'avatar_url',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
            'membership_expires_at' => 'datetime',
        ];
    }

    /**
     * 获取用户创建的所有账本
     */
    public function createdBooks()
    {
        return $this->hasMany(MoneyBook::class, 'user_id');
    }

    /**
     * 获取用户参与的所有账本
     */
    public function books()
    {
        return $this->belongsToMany(MoneyBook::class, 'money_book_users', 'user_id', 'book_id')
                    ->withPivot('role')
                    ->withTimestamps();
    }

    /**
     * 获取用户的所有交易记录
     */
    public function transactions()
    {
        return $this->hasMany(MoneyTransaction::class, 'user_id');
    }

    /**
     * 获取用户的默认账本
     */
    public function defaultBook()
    {
        return $this->belongsTo(MoneyBook::class, 'default_book_id');
    }

    /**
     * 获取用户的当前默认账本（如果没有设置则返回第一个参与的账本）
     */
    public function getCurrentDefaultBook()
    {
        if ($this->default_book_id && $this->defaultBook) {
            return $this->defaultBook;
        }

        // 如果没有设置默认账本，返回第一个参与的账本
        return $this->books()->first();
    }

    /**
     * 检查用户是否为会员
     */
    public function isMember()
    {
        if ($this->membership_type === 'permanent') {
            return true;
        }

        return $this->membership_expires_at && $this->membership_expires_at->isFuture();
    }

    /**
     * 获取会员剩余天数
     */
    public function getMembershipDaysLeft()
    {
        if ($this->membership_type === 'permanent') {
            return -1; // 永久会员返回-1
        }

        if (!$this->membership_expires_at || $this->membership_expires_at->isPast()) {
            return 0;
        }

        return $this->membership_expires_at->diffInDays(now());
    }

    /**
     * 获取会员类型名称
     */
    public function getMembershipTypeName()
    {
        $types = [
            'day' => '日卡',
            'month' => '月卡',
            'year' => '年卡',
            'permanent' => '永久卡'
        ];

        return $types[$this->membership_type] ?? '普通用户';
    }

    /**
     * 获取用户使用的兑换码
     */
    public function membershipCodes()
    {
        return $this->hasMany(MembershipCode::class, 'used_by');
    }

    public function getAvatarUrlAttribute()
    {
       return $this->avatar ? Storage::url($this->avatar) : '';
    }

    /**
     * 获取用户当前使用次数
     *
     * @param string $usageType 使用类型，如 record_by_text, record_by_audio, record_by_image
     * @return int 当前使用次数
     */
    public function getCurrentUsageCount($usageType)
    {
        $today = date('Ymd');
        $cacheKey = "ai_usage_{$usageType}:{$today}:{$this->id}";
        return cache()->get($cacheKey, 0);
    }

    /**
     * 增加使用次数
     * 使用原子操作increment来避免高并发场景下的竞态条件问题
     *
     * @param string $usageType 使用类型，如 record_by_text, record_by_audio, record_by_image
     * @return int 增加后的使用次数
     */
    public function incrementUsageCount($usageType)
    {
        $today = date('Ymd');
        $cacheKey = "ai_usage_{$usageType}:{$today}:{$this->id}";
        // 使用increment原子操作，避免高并发下的竞态条件
        $newCount = cache()->increment($cacheKey, 1);

        // 设置过期时间（因为increment可能不会自动设置过期时间）
        if ($newCount === 1) {
            // 当计数为1时，表示是第一次设置，需要设置过期时间
            // 重新put值并设置过期时间，这不会影响原子性，因为值已经被increment设置
            cache()->put($cacheKey, 1, now()->addHours(24));
        }

        return $newCount;
    }

    /**
     * 判断用户是否有权限继续使用特定功能
     *
     * @param string $usageType 使用类型，如 record_by_text, record_by_audio, record_by_image
     * @return bool 是否可以继续使用
     */
    public function canUseFeature($usageType)
    {
        // 会员无限制使用
        if ($this->isMember()) {
            return true;
        }

        // 非会员检查使用次数限制
        $limit = non_member_limits[$usageType] ?? 0;
        $currentCount = $this->getCurrentUsageCount($usageType);

        return $currentCount < $limit;
    }

    public function createDefaultBookForUser()
    {
        try {
            $userId = $this['id'];
            // 创建默认账本
            $book = MoneyBook::create([
                'name' => '我的账本',
                'description' => '默认账本',
                'user_id' => $userId,
                'is_default' => true,
            ]);
            $this->default_book_id = $book->id;
            $this->save();
            return $book;
        } catch (\Exception $e) {
            \Log::error('创建默认账本失败: ' . $e->getMessage());
            return false;
        }
    }
}
